package cn.gemiman.daoyi.module.cms.service.appsite;

import cn.gemiman.daoyi.framework.common.enums.CommonStatusEnum;
import cn.gemiman.daoyi.framework.common.enums.UserTypeEnum;
import cn.gemiman.daoyi.framework.common.pojo.PageResult;
import cn.gemiman.daoyi.framework.common.util.object.BeanUtils;
import cn.gemiman.daoyi.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.gemiman.daoyi.framework.security.core.LoginUser;
import cn.gemiman.daoyi.framework.security.core.util.SecurityFrameworkUtils;
import cn.gemiman.daoyi.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import cn.gemiman.daoyi.module.cms.controller.admin.appsite.vo.AppSitePageReqVO;
import cn.gemiman.daoyi.module.cms.controller.admin.appsite.vo.AppSiteSaveReqVO;
import cn.gemiman.daoyi.module.cms.controller.admin.appsitecomment.vo.AppSiteCommentUpdateStatusReqVO;
import cn.gemiman.daoyi.module.cms.controller.app.appsite.vo.AppAppSiteStatisticRespVO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.appsite.AppSiteDO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.articlecategory.CmsArticleCategoryDO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.articledetail.ArticleDetailDO;
import cn.gemiman.daoyi.module.cms.dal.mysql.appsite.AppSiteMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.articlecategory.CmsArticleCategoryMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.articledetail.ArticleDetailMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.tagdictionary.TagDictionaryMapper;
import cn.gemiman.daoyi.module.member.api.user.MemberUserApi;
import cn.gemiman.daoyi.module.member.api.user.dto.MemberUserRespDTO;
import cn.gemiman.daoyi.module.system.api.user.AdminUserApi;
import cn.gemiman.daoyi.module.system.api.user.dto.AdminUserRespDTO;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import static cn.gemiman.daoyi.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.gemiman.daoyi.module.cms.enums.ErrorCodeConstants.*;

/**
 * 站点 Service 实现类
 *
 * @author 道一源码
 */
@Service
@Validated
public class AppSiteServiceImpl implements AppSiteService {

    @Resource
    private AppSiteMapper appSiteMapper;
    @Resource
    private ArticleDetailMapper articleDetailMapper;
    @Resource
    private CmsArticleCategoryMapper cmsArticleCategoryMapper;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private TagDictionaryMapper tagDictionaryMapper;

    @Override
    public Long createAppSite(AppSiteSaveReqVO createReqVO) {
        createReqVO.setStatus(CommonStatusEnum.DISABLE.getStatus());
        createReqVO.setApproveStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus());
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (null != loginUser) {
            createReqVO.setUserType(loginUser.getUserType());
            createReqVO.setUserId(loginUser.getId());
            if (UserTypeEnum.ADMIN.getValue().equals(createReqVO.getUserType())) {
                createReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
                createReqVO.setApproveStatus(BpmProcessInstanceStatusEnum.APPROVE.getStatus());
            }
        }
        if (null != createReqVO.getId()) {
            AppSiteDO appSiteDO = validateAppSiteExists(createReqVO.getId());
            if (UserTypeEnum.ADMIN.getValue().equals(appSiteDO.getUserType()) || !ObjectUtil.equal(createReqVO.getUserId(), appSiteDO.getUserId())) {
                throw exception(APP_SITE_NOT_SELF);
            }
            createReqVO.setBindDomain(null);
            this.updateAppSite(createReqVO);
            return createReqVO.getId();
        }
        if (CharSequenceUtil.isBlank(createReqVO.getAppId())) {
            createReqVO.setAppId(IdUtil.fastUUID());
        }
        if (null != createReqVO.getUserId() && null != createReqVO.getUserType()) {
            if (UserTypeEnum.MEMBER.getValue().equals(createReqVO.getUserType())) {
                MemberUserRespDTO checkedData = memberUserApi.getUser(createReqVO.getUserId()).getCheckedData();
                createReqVO.setUserNickname(checkedData.getNickname());
                createReqVO.setUserAvatar(checkedData.getAvatar());
            } else if (UserTypeEnum.ADMIN.getValue().equals(createReqVO.getUserType())) {
                AdminUserRespDTO checkedData = adminUserApi.getUser(createReqVO.getUserId()).getCheckedData();
                createReqVO.setUserNickname(checkedData.getNickname());
                createReqVO.setUserAvatar(checkedData.getAvatar());
            }
        }
        AppSiteDO exists = appSiteMapper.selectOne(new LambdaQueryWrapperX<AppSiteDO>()
                .like(AppSiteDO::getBindDomain, createReqVO.getBindDomain()), false);
        if (null != exists) {
            throw exception(APP_SITE_EXISTS);
        }
        // 插入
        AppSiteDO appSite = BeanUtils.toBean(createReqVO, AppSiteDO.class);
        appSite.setAppDescription(CharSequenceUtil.nullToEmpty(appSite.getAppDescription()));
        if (null == appSite.getAppPhotos() && null != appSite.getAppLogoUrl()) {
            appSite.setAppPhotos(CollUtil.toList(appSite.getAppLogoUrl()));
        }
        appSiteMapper.insert(appSite);
        // 返回
        return appSite.getId();
    }

    @Override
    public void updateAppSiteStatus(AppSiteCommentUpdateStatusReqVO updateReqVO) {
        // 校验存在
        validateAppSiteExists(updateReqVO.getId());
        // 更新 状态
        appSiteMapper.updateById(new AppSiteDO().setId(updateReqVO.getId())
                .setStatus(updateReqVO.getStatus())
        );
    }

    @Override
    public void updateAppSiteApproveStatus(AppSiteCommentUpdateStatusReqVO updateReqVO) {
        // 校验存在
        AppSiteDO commentExists = validateAppSiteExists(updateReqVO.getId());
        if (!BpmProcessInstanceStatusEnum.RUNNING.getStatus().equals(commentExists.getApproveStatus())) {
            throw exception(APP_SITE_COMMENT_NOT_RUNNING);
        }
        // 更新 状态
        appSiteMapper.updateById(new AppSiteDO().setId(updateReqVO.getId())
                .setApproveStatus(updateReqVO.getApproveStatus())
        );
        if (BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(updateReqVO.getApproveStatus()) && CommonStatusEnum.DISABLE.getStatus().equals(commentExists.getStatus())) {
            appSiteMapper.updateById(new AppSiteDO().setId(updateReqVO.getId())
                    .setStatus(CommonStatusEnum.ENABLE.getStatus())
            );
        }
    }

    @Override
    public void updateAppSite(AppSiteSaveReqVO updateReqVO) {
        // 校验存在
        validateAppSiteExists(updateReqVO.getId());
        // 更新
        AppSiteDO updateObj = BeanUtils.toBean(updateReqVO, AppSiteDO.class);
        appSiteMapper.updateById(updateObj);
    }

    @Override
    public void deleteAppSite(Long id) {
        // 校验存在
        validateAppSiteExists(id);
        // 删除
        appSiteMapper.deleteById(id);
    }

    private AppSiteDO validateAppSiteExists(Long id) {
        AppSiteDO appSiteDO = appSiteMapper.selectById(id);
        if (appSiteDO == null) {
            throw exception(APP_SITE_NOT_EXISTS);
        }
        return appSiteDO;
    }

    @Override
    public AppSiteDO getAppSite(Long id) {
        return appSiteMapper.selectById(id);
    }

    @Override
    public PageResult<AppSiteDO> getAppSitePage(AppSitePageReqVO pageReqVO) {
        return appSiteMapper.selectPage(pageReqVO);
    }

    @Override
    public AppSiteDO getAppSite(String appId) {
        return appSiteMapper.selectOne(new LambdaQueryWrapperX<AppSiteDO>()
                .eq(AppSiteDO::getAppId, appId), false);
    }

    @Override
    public AppAppSiteStatisticRespVO getStatistic(String appId) {
        AppAppSiteStatisticRespVO respVO = new AppAppSiteStatisticRespVO();
        respVO.setArticleCount(articleDetailMapper.selectCount(ArticleDetailDO::getAppId, appId));
        respVO.setTagCount(tagDictionaryMapper.selectCount());
        respVO.setCategoryCount(cmsArticleCategoryMapper.selectCount(CmsArticleCategoryDO::getAppId, appId));
        respVO.setUserCount(memberUserApi.getUserCount().getCheckedData());
        return respVO;
    }

    @Override
    public Long addAppSiteView(String appId) {
        appSiteMapper.addAppSiteView(appId);
        return getAppSite(appId).getViewTimes();
    }

}
